home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BMUG Revelations
/
BMUG Revelations.toast
/
Utilities
/
Text and Speech
/
UUTool
/
uu engine
/
UUIntf.p
< prev
Wrap
Text File
|
1991-06-12
|
11KB
|
343 lines
{*}
{** Project: uu**code engine}
{** Author: Bernhard S. Wieser}
{** Module: UUGlue.p}
{** Date: 5/19/91}
{** Revised: 6/1/91 L.R. suggested user allocate buffers}
{** 6/8/91 L.R. suggested Pascal calling conventions}
{** - removed table/engine globals}
{** 6/11/91 Converted to Pascal by Leonard Rosenthol}
{** Version: 1.0.2}
{**}
{** Preface:}
{** uu**code engine is © by Bernhard S. Wieser and Octavian Micro}
{** development, all rights reserved. Please read the accompanying}
{** licensing agreement before use.}
{**}
{** Purpose:}
{** This code should be compiled with the program using the}
{** uu**coding engine. It loads and unloads the resource, as well as}
{** providing 'glue' to the contained routines.}
{** The 'glue' routines bind the various uu**coding functions}
{** contained in the resource file to known subroutines names, thus}
{** providing a means of easy access from a high level language.}
{** The underlying resource routines use the Pascal calling convention.}
{** The resources occupy <3K of memory. You must make room for}
{** the buffers, except for the uuencode() and uudecode() routines which}
{** require that you specify how much (contiguous) space they will allocate.}
{** To be safe (especially with noxious INITs which invade an}
{** applications memory), allocate at least (volume buffer size)}
{** 524 bytes + some so as not to unexpectedly run out of memory.}
{**}
{** Conditions of use:}
{** Visible credit to Bernhard S. Wieser and Octavian Micro}
{** Development MUST be given. Written permission MUST be obtained}
{** upon any distribution, with a licensing fee pending depending on what}
{** it is used for.}
{**}
{** Algorithm:}
{** uuencoding takes 24 bit from input stream (3 bytes) and splits}
{** it into 32 bits (4 bytes) output. Each output byte has the top 2}
{** bits clear, and can be translated into a printable character. The}
{** traditional way is to simply add $20 (space). uudecoding simply}
{** subtracts $20, strips the top 2 bits from input, and stuffs things }
{** back together.}
{** The encoding engine uses a translate table. Two reasons.}
{** First, its faster than bit manipulation. Second, I can avoid}
{** some characters (like space, which some mailers despise). This}
{** table can be changed so long as the character, when its top 2}
{** bits are stripped, equals its index into the table.}
{**}
{** Example:}
{** '`' = $60, ' ' = $20 <- encoded}
{** AND $3F $3F}
{** ___ ___}
{** $20 $20}
{** SUB $20 $20}
{** ___ ___}
{** $00 $00 <- decoded}
{**}
{** Data Structures:}
{** Here is the resource 'UENG' 128 jump table:}
{** OFFSET CODE}
{** 0 BRA encode}
{** +4 BRA encodeOne}
{** +8 BRA encodeLine}
{** +C BRA uuencode}
{** +10 BRA decode}
{** +14 BRA decodeOne}
{** +18 BRA decodeLine}
{** +1C BRA uudecode}
{**}
{** Resource 'HEXA' 128 is an array of 64 printable characters}
{** which equal their index when the top two bits are stripped.}
{**}
{** Revisions}
{** User must now maintain the table and engine handles. User}
{** Must also remember these are LOCKED so must be dereferenced and}
{** passed as pointers to the core routines.}
{*}
UNIT UUIntf;
INTERFACE
{Main Load/Unload routines}
FUNCTION UULoad (VAR table, engine: Handle): OSErr;
PROCEDURE UUnload (VAR table, engine: Handle);
{Core routines for UUEncoding}
FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
FUNCTION encode (three, table, engine: Ptr): OSType;
FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
{Core routines for UUDecoding}
FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
FUNCTION decode (s, engine: Ptr): OSType;
FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
IMPLEMENTATION
{*}
{** UULoad}
{** Load engine, table, move them high and lock them.}
{**}
{** Parameters}
{** table handle to the encode table - passed back as a VAR}
{** engine handle to the engine base - passed back as a VAR}
{**}
{** Returns}
{** resource or memory errors}
{*}
FUNCTION UULoad (VAR table, engine: Handle): OSErr;
BEGIN
UULoad := 0;
table := GetResource('HEXA', 128);
IF (table <> NIL) THEN
BEGIN
engine := GetResource('UENG', 128);
IF (engine <> NIL) THEN
BEGIN
MoveHHi(table);
MoveHHi(engine);
HLock(table);
HLock(engine);
END
ELSE
BEGIN
UULoad := ResError;
ReleaseResource(table);
END;
END
ELSE
UULoad := ResError;
END;
{*}
{** UUnload}
{** Get rid of the uu resources.}
{**}
{** Parameters}
{** table handle to the encode table}
{** engine handle to the engine base}
{**}
{** Returns}
{** nothing}
{*}
PROCEDURE UUnload (VAR table, engine: Handle);
BEGIN
HUnlock(table);
HUnlock(engine);
ReleaseResource(table);
ReleaseResource(engine);
END;
{* **}
{** The core Pascal glue routines! **}
{** *}
{*}
{** encodeOne}
{** Encode one byte only, only use low 6 bits input.}
{**}
{** Parameters}
{** c the character (passed as integer)}
{** table pointer to the encode table}
{** engine pointer to the engine base}
{**}
{** Returns}
{** the encoded character (as integer)}
{*}
FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
FUNCTION DoIt (c: INTEGER; table, engine: Ptr): INTEGER;
INLINE
$205F, $4EA8, $0004;
BEGIN
encodeOne := DoIt(c, table, engine);
END;
{*}
{** encode}
{** Take three bytes input, return four bytes uucoded output.}
{**}
{** Parameters}
{** three pointer to an array holding at least three characters}
{** table pointer to the encode table}
{** engine pointer to the engine base}
{**}
{** Returns}
{** four characters of encoded data in a long word}
{*}
FUNCTION encode (three, table, engine: Ptr): OSType;
FUNCTION DoIt (three, table, engine: Ptr): OSType;
INLINE
$205F, $4E90;
BEGIN
encode := DoIt(three, table, engine);
END;
{*}
{** encodeLine}
{** Take 'insize' bytes from buffer 'in' and encode to buffer 'out'.}
{** The size of the encode data is returned (including length and CR).}
{** Remember, input buffer should be divisible by 3, and output size}
{** will be 4 times the quotient (plus 2 for length and CR).}
{**}
{** Parameters}
{** inPtr pointer to input buffer}
{** insize size of input buffer}
{** outPtr pointer to output buffer}
{** table pointer to the encode table}
{** engine pointer to the engine base}
{**}
{** Returns}
{** length of encoded data in output buffer}
{*}
FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
FUNCTION DoIt (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
INLINE
$205F, $4EA8, $0008;
BEGIN
encodeLine := DoIt(inPtr, inSize, outPtr, table, engine);
END;
{*}
{** uuencode}
{** Encode file 'infile' to output file 'outfile', calling}
{** 'routine' as buffers are flushed. 'routine' should be NULL}
{** if there are no periodic tasks to perform. 'numbufrs' tells the}
{** engine how many input/output buffers to allocate. An input}
{** buffer is 45 bytes long, and output buffer is 62 bytes long.}
{** Example, numbufrs = 1024 would allocate 45K+62K = 107K.}
{**}
{** Parameters}
{** infile input file's file reference number}
{** outfile output file's " " "}
{** numbufrs number of i/o buffers to use (not size of!)}
{** routine update procedure pointer (or NIL)}
{** table pointer to the encode table}
{** engine pointer to the engine base}
{**}
{** Returns}
{** any error encountered}
{*}
FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
FUNCTION DoIt (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
INLINE
$205F, $4EA8, $000C;
BEGIN
uuencode := DoIt(infile, outfile, numbufrs, routine, table, engine);
END;
{*}
{** decodeOne}
{** Decode one coded character.}
{**}
{** Parameters}
{** c encoded character (integer passed)}
{** engine pointer to the engine's base address}
{**}
{** Returns}
{** the decoded character (integer)}
{*}
FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
FUNCTION DoIt (c: INTEGER; engine: Ptr): INTEGER;
INLINE
$205F, $4EA8, $0014;
BEGIN
decodeOne := DoIt(c, engine);
END;
{*}
{** decode}
{** Decode 4 bytes to 3.}
{**}
{** Parameters}
{** s pointer to 4 byte array of data to decode}
{** engine pointer to the engine's base address}
{**}
{** Returns}
{** the decoded data (in the upper 8 bits of a long word)}
{*}
FUNCTION decode (s, engine: Ptr): OSType;
FUNCTION DoIt (s, engine: Ptr): OSType;
INLINE
$205F, $4EA8, $0010;
BEGIN
decode := DoIt(s, engine);
END;
{*}
{** decodeLine}
{** Decode a uucoded input in 'in' to buffer 'out'. Returns}
{** length of decoded data.}
{**}
{** Parameters}
{** inPtr pointer to an input buffer, of which first encoded}
{** character is buffer length}
{** outPtr pointer to the buffer to contained decoded data,}
{** generally < 80 bytes is required.}
{** engine pointer to the engine's base address}
{**}
{** Returns}
{** the amount of decoded data (or buffer size if you like)}
{*}
FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
FUNCTION DoIt (inPtr, outPtr, engine: Ptr): LONGINT;
INLINE
$205F, $4EA8, $0018;
BEGIN
decodeLine := DoIt(inPtr, outPtr, engine);
END;
{*}
{** uudecode}
{** Decode 'infile' to 'outfile', calling 'routine' on buffer flush.}
{** 'bufsizes', unlike in uuencode, is the actual buffer size in bytes}
{** that you want to allocated for input and output buffers.}
{** NEVER allocate a buffer less than 10 bytes (it would be very silly).}
{** Suggested values are multiples of 524 bytes.}
{** Function returns error.}
{**}
{** Parameters}
{** infile file reference number of input (encoded) data}
{** outfile " " " of output (decoded) data}
{** bufsizes the size in bytes for input and output buffers}
{** to be allocated by uudecode()}
{** routine the update procedure (or NIL if none)}
{** engine pointer to the engine's base address}
{**}
{** Returns}
{** any errors encountered}
{*}
FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
FUNCTION DoIt (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
INLINE
$205F, $4EA8, $001C;
BEGIN
uudecode := DoIt(infile, outfile, bufsizes, routine, engine);
END;
END.